场景
经常会有一些弹窗的场景,很多时候,我们用的是 AlertDialog
或者 Dialog
来做。
AlertDialog
AlertDialog 本来就是系统封装好的一个弹窗控件,用起来很简单也很舒服,但是定制起来就不是很方便。
Dialog
所以更多的情况是 继承 Dialog 自己来实现一个 Dialog 。
DialogFragment
DialogFragment 是在 3.0 后引入的,是一种特殊的 Fragment。可以理解为是 Dialog 和 Fragment 的融合体。Google 也推荐使用 DialogFragment 来代替 Dialog。
优点:
由于 DialogFragment 继承自 fragment , 所以拥有 Fragment 的什么周期,和 Fragment 的 特性。
所以可以通过 管理 Fragment 的生命周期来控制 Dialog ,也可以通过 Fragment 来监听一些时间,比如 屏幕旋转 和 Back 键 的监听等。
注意点:
其实也是 Fragment 的一个注意点。
传递数据的时候,尽量使用 setArguments()
来传递数据。因为生命周期变化的时候,setArguments()
传递过来的参数会保存起来,重新构建的时候,数据不会丢失。
DialogFragment 使用
可以使用 onCreateDialog()
或者 onCreateView()
来创建 界面,只需要实现一个就可以了。
在使用 onCreateView()
创建的时候,会有一个默认的主题,导致会有空白背景 ,和 标题栏。
在onStart()
里面添加下面的代码就可以去掉了。
Dialog dialog = getDialog();
Window window = dialog.getWindow();
window.setBackgroundDrawable(getResources().getDrawable(R.color.transparency));//背景透明
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); //设置无标题
关于 DialogFragment 的思考
既然 DialogFragment 既可以是 Dialog 也可以是 Fragment 。那 DialogFragment 到底是什么东西呢。
答案是 Dialog , 但是是一个可以感知 Fragment 生命周期的 Dialog。
通过查看源码,可以发现 DialogFragment
其实是在内部维护一个 Dialog ,然后再把 Fragment 创建的 View , 通过 Dialog 的 setContentView()
设置进去。
要显示的时候,也就是调用 DialogFragment 的 show() 方法来显示的时候会传进来一个 FragmentManager
通过这个 FragmentManager
我们的 Dialogfragment 就可以监听到 Fragment 的生命周期了。
让我们看一下源码:
public void show(FragmentManager manager, String tag) {
mDismissed = false;
mShownByMe = true;
FragmentTransaction ft = manager.beginTransaction();
ft.add(this, tag);
ft.commit();
}
再看一下几个关键的 方法:
@Override
public void onStart() {
super.onStart();
if (mDialog != null) {
mViewDestroyed = false;
mDialog.show();
}
}
现在知道 为什么要在 onStart()
后面才能去掉 背景和 标题了吧?
什么?还不知道?
这里我们是通过 获取到 window 对象,然后把背景设置成透明。
而第一步是要获取到 window 对象,但是 Dialog 是要在 调用 show() 方法后才会添加到 window 里面,我们才能获取到 window 对象。在 onStart
方法里面就调用了 show 方法。
解决思路
既然知道 DialogFragment 是 Dialog , Dialog 又是通过 WindowManager 来添加的一个 window ,那就好办了,通过修改 window 的配置就可以了。
当然,也还是要在 onStart
方法之后 使用。 至于原因嘛,你懂的 ,刚才已经说过了。
Window window = getDialog().getWindow();
window.setLayout(300,200);
当然位置什么的也是可以控制的,也是通过控制 window 来实现的。